// /////////////////////////////////////////////////////////////////////////////
//
// Name:            ColourFrame.cpp
// Author:          Michael Bartsch
//
// Desc :           This file contains the CColourFrame Class. This class
//                  contains the Color Frame which is responsible for
//                  outputing the colour analysis.
//
// License:         Copyright (C) 2008-2009 Michael Bartsch
//
//                  This program is free software: you can redistribute it
//                  and/or modify it under the terms of the GNU General Public
//                  License as published by the Free Software Foundation,
//                  either version 3 of the License, or (at your option) any
//                  later version.
//
//                  This program is distributed in the hope that it will be
//                  useful, but WITHOUT ANY WARRANTY; without even the implied
//                  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
//                  PURPOSE. See the GNU General Public License for more
//                  details.
//
//                  You should have received a copy of the GNU General Public
//                  License along with this program. If not, see
//                  <http://www.gnu.org/licenses/>.
//
// /////////////////////////////////////////////////////////////////////////////

// Include required header file(s).
#include "ColourFrame.h"


// CColourFrame Events. - [ BEGIN ]
BEGIN_EVENT_TABLE(CColourFrame, wxFrame)
   EVT_CLOSE(CColourFrame::onClose)
   EVT_MENU(wxID_EXIT,              CColourFrame::onQuit)

   EVT_CHECKBOX(COF_EnableTarget,    CColourFrame::onEnableTarget)
   EVT_SPINCTRL(COF_TargetR,         CColourFrame::onTargetRChange)
   EVT_SPINCTRL(COF_TargetG,         CColourFrame::onTargetGChange)
   EVT_SPINCTRL(COF_TargetB,         CColourFrame::onTargetBChange)
   EVT_SPINCTRL(COF_TargetMargin,    CColourFrame::onTargetMarginChange)
   EVT_SPINCTRL(COF_TargetBorder,    CColourFrame::onTargetBorderChange)
END_EVENT_TABLE()
// CColourFrame Events. - [ END ]


// CColourFrame.
// Constructor.
CColourFrame::CColourFrame(wxWindow *parent)
#ifdef __OS_WINDOWS__
: wxFrame(parent, wxID_ANY, _T("Aia|CP - Colour Analysis"), wxPoint(0,0), wxSize(1032,648), wxDEFAULT_FRAME_STYLE & ~ (wxRESIZE_BORDER | wxRESIZE_BOX | wxMAXIMIZE_BOX))
#else
: wxFrame(parent, wxID_ANY, _T("Aia|CP - Colour Analysis"), wxPoint(0,0), wxSize(1024,632), wxDEFAULT_FRAME_STYLE & ~ (wxRESIZE_BORDER | wxRESIZE_BOX | wxMAXIMIZE_BOX))
#endif
{
    // Set internal variables.
    frameParent = (CMainFrame*)parent;
    pColourAnalyser = CColourAnalyser::Instance();

    // Tell wxAuiManager to manage this frame.
    frameManager.SetManagedWindow(this);
    frameManager.SetFlags(wxAUI_MGR_DEFAULT & ~ wxAUI_MGR_ALLOW_FLOATING);

    // Init the Menu Bar.
    wxMenuBar* menuBar = new wxMenuBar();

    // Menu->File Menu
    wxMenu *fileMenu = new wxMenu;

    wxMenuItem *fmQuit = new wxMenuItem(fileMenu, wxID_EXIT, _T("&Quit\tCtrl+Q"), _T("Close the Colour Analyser"));
    fmQuit->SetBitmap(wxIcon("../media/file-quit.png", wxBITMAP_TYPE_PNG));
    fileMenu->Append(fmQuit);

    // Add submenu's to the Menu Bar.
    menuBar->Append(fileMenu, _T("&File"));

    // Associate the Menu Bar with the frame.
    SetMenuBar(menuBar);

    // Init the Status Bar.
    CreateStatusBar(1, 0, -1);

    // Create the panes.
    cameraPanel = new CCameraPanel(this);
    cubePanel = new CCubePanel(this);
    colourPanelR = new CRGBPanel(this, RGBPanel_R);
    colourPanelG = new CRGBPanel(this, RGBPanel_G);
    colourPanelB = new CRGBPanel(this, RGBPanel_B);

    // Settings pane.
    wxPanel *settingsPanel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(246,562));
    wxSizer *settingsSizer = new wxBoxSizer(wxVERTICAL);

    // Target colour.
    wxPanel *targetColourPanel = new wxPanel(settingsPanel, wxID_ANY);
    wxSizer *targetColourSizer = new wxStaticBoxSizer(wxVERTICAL, targetColourPanel, _T("Target colour"));

    // Target colour -> Enable target.
    enableTarget = new wxCheckBox(targetColourPanel, COF_EnableTarget, wxT("Enable target"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
    targetColourSizer->Add(enableTarget, wxSizerFlags().Expand().Border(wxTOP, 2));

    if(pColourAnalyser->getIsTarget())
      enableTarget->SetValue(true);

    else enableTarget->SetValue(false);

    // Target colour -> Red
    wxSizer *tempSizer = new wxBoxSizer(wxHORIZONTAL);
    wxString tempString;

    tempSizer->Add(new wxStaticText(targetColourPanel, wxID_ANY, wxT("R:")), wxSizerFlags(1).Expand().Border(wxTOP | wxRIGHT, 3));

    tempString.Clear();
    tempString.Printf(wxT("%d"), (int)pColourAnalyser->getTargetR());
    targetR = new wxSpinCtrl(targetColourPanel, COF_TargetR, tempString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 255, 0);
    tempSizer->Add(targetR, wxSizerFlags(3).Expand());

    targetColourSizer->Add(tempSizer, wxSizerFlags().Expand().Border(wxTOP, 2));

    // Target colour -> Green
    tempSizer = new wxBoxSizer(wxHORIZONTAL);

    tempSizer->Add(new wxStaticText(targetColourPanel, wxID_ANY, wxT("G:")), wxSizerFlags(1).Expand().Border(wxTOP | wxRIGHT, 3));

    tempString.Clear();
    tempString.Printf(wxT("%d"), (int)pColourAnalyser->getTargetG());
    targetG = new wxSpinCtrl(targetColourPanel, COF_TargetG, tempString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 255, 0);
    tempSizer->Add(targetG, wxSizerFlags(3).Expand());

    targetColourSizer->Add(tempSizer, wxSizerFlags().Expand().Border(wxTOP, 2));

    // Target colour -> Blue
    tempSizer = new wxBoxSizer(wxHORIZONTAL);

    tempSizer->Add(new wxStaticText(targetColourPanel, wxID_ANY, wxT("B:")), wxSizerFlags(1).Expand().Border(wxTOP | wxRIGHT, 3));

    tempString.Clear();
    tempString.Printf(wxT("%d"), (int)pColourAnalyser->getTargetB());
    targetB = new wxSpinCtrl(targetColourPanel, COF_TargetB, tempString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 255, 0);
    tempSizer->Add(targetB, wxSizerFlags(3).Expand());

    targetColourSizer->Add(tempSizer, wxSizerFlags().Expand().Border(wxTOP, 2));

    // Target colour -> Set sizer.
    targetColourPanel->SetSizer(targetColourSizer);
    targetColourSizer->SetSizeHints(targetColourPanel);

    // Solver
    wxPanel *solverPanel = new wxPanel(settingsPanel, wxID_ANY);
    wxSizer *solverSizer = new wxStaticBoxSizer(wxVERTICAL, solverPanel, _T("Solver"));

    // Solver -> Margin
    tempSizer = new wxBoxSizer(wxHORIZONTAL);

    tempSizer->Add(new wxStaticText(solverPanel, wxID_ANY, wxT("Margin:")), wxSizerFlags(1).Expand().Border(wxTOP | wxRIGHT, 3));

    tempString.Clear();
    tempString.Printf(wxT("%d"), (int)pColourAnalyser->getTargetMargin());
    targetMargin = new wxSpinCtrl(solverPanel, COF_TargetMargin, tempString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 127, 0);
    tempSizer->Add(targetMargin, wxSizerFlags(3).Expand());

    solverSizer->Add(tempSizer, wxSizerFlags().Expand().Border(wxTOP, 2));

    // Solver -> Border
    tempSizer = new wxBoxSizer(wxHORIZONTAL);

    tempSizer->Add(new wxStaticText(solverPanel, wxID_ANY, wxT("Border:")), wxSizerFlags(1).Expand().Border(wxTOP | wxRIGHT, 3));

    tempString.Clear();
    tempString.Printf(wxT("%d"), (int)pColourAnalyser->getTargetBorder());
    targetBorder = new wxSpinCtrl(solverPanel, COF_TargetBorder, tempString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 101376, 0);
    tempSizer->Add(targetBorder, wxSizerFlags(3).Expand());

    solverSizer->Add(tempSizer, wxSizerFlags().Expand().Border(wxTOP, 2));

    // Target colour -> Set sizer.
    solverPanel->SetSizer(solverSizer);
    solverSizer->SetSizeHints(solverPanel);

    // Set the main sizer.
    settingsSizer->Add(targetColourPanel, wxSizerFlags().Expand().Border(wxALL, 3));
    settingsSizer->Add(solverPanel, wxSizerFlags().Expand().Border(wxALL, 3));

    settingsPanel->SetSizer(settingsSizer);
    settingsSizer->SetSizeHints(settingsPanel);

    // Add the panes.
    frameManager.AddPane(cameraPanel, wxAuiPaneInfo().Name(wxT("paneCamera")).
                         Caption(wxT("Camera")).Top().CloseButton(false).
                         MaximizeButton(false).Resizable(false));

    frameManager.AddPane(cubePanel, wxAuiPaneInfo().Name(wxT("paneCube")).
                         Caption(wxT("Colour Cube")).Top().Position(1).CloseButton(false).
                         MaximizeButton(false).Resizable(false));

    frameManager.AddPane(colourPanelR, wxAuiPaneInfo().Name(wxT("paneRed")).
                         Caption(wxT("Red")).Bottom().CloseButton(false).
                         MaximizeButton(false).Resizable(false));

    frameManager.AddPane(colourPanelG, wxAuiPaneInfo().Name(wxT("paneGreen")).
                         Caption(wxT("Green")).Bottom().Position(1).CloseButton(false).
                         MaximizeButton(false).Resizable(false));

    frameManager.AddPane(colourPanelB, wxAuiPaneInfo().Name(wxT("paneBlue")).
                         Caption(wxT("Blue")).Bottom().Position(2).CloseButton(false).
                         MaximizeButton(false).Resizable(false));

    frameManager.AddPane(settingsPanel, wxAuiPaneInfo().Name(wxT("paneSettings")).
                         Caption(wxT("Settings")).Right().Layer(1).Position(1).
                         CloseButton(false).Resizable(false).MinSize(wxSize(246,560)));

    frameManager.Update();

}

// Updates the frame and it's childs.
void CColourFrame::update()
{
    if(!pColourAnalyser->getIsMatchR())
      targetR->SetForegroundColour(wxColor(*wxRED));

    if(!pColourAnalyser->getIsMatchG())
      targetG->SetForegroundColour(wxColor(*wxRED));

    if(!pColourAnalyser->getIsMatchB())
      targetB->SetForegroundColour(wxColor(*wxRED));

	cubePanel->createCloud();

    Refresh();
}

// Event Functions. - [ BEGIN ]
void CColourFrame::onClose(wxCloseEvent &event)
{
    // Deinitialise wxAuiManager.
    frameManager.UnInit();

    // Reset frame state.
    frameParent->resetColourFrame();

    // Destroy frame.
    Destroy();
}

void CColourFrame::onQuit(wxCommandEvent& event)
{
    Close(true);
}

void CColourFrame::onEnableTarget(wxCommandEvent &event)
{
    pColourAnalyser->setIsTarget(enableTarget->GetValue());
}

void CColourFrame::onTargetRChange(wxSpinEvent &event)
{
    pColourAnalyser->setTargetR(targetR->GetValue());
}

void CColourFrame::onTargetGChange(wxSpinEvent &event)
{
    pColourAnalyser->setTargetG(targetG->GetValue());
}

void CColourFrame::onTargetBChange(wxSpinEvent &event)
{
    pColourAnalyser->setTargetB(targetB->GetValue());
}

void CColourFrame::onTargetMarginChange(wxSpinEvent &event)
{
    pColourAnalyser->setTargetMargin(targetMargin->GetValue());
}

void CColourFrame::onTargetBorderChange(wxSpinEvent &event)
{
    pColourAnalyser->setTargetBorder(targetR->GetValue());
}
// Event Functions. - [ END ]

// Get Functions. - [ BEGIN ]
// Get Functions. - [ END ]

// End of File
